#pragma once
#include <string>
#include <memory>
#include <string.h>
#include <iostream>
#include <unordered_map>
#include "ThostFtdcUserApiStruct.h"

// 定义项目全局结构体 本文件禁止修改

constexpr const uint32_t MAX_INSTRUMENT_LENGTH =	32;
constexpr const uint32_t MAX_EXCHANGE_LENGTH = 16;

typedef enum tagOptionType
{
	OT_None = 0,
	OT_Call = '1',		//看涨期权
	OT_Put = '2'		//看跌期权
} OptionType;

typedef enum tagContractCategory
{
	CC_Stock,			//股票
	CC_Future,			//期货
	CC_FutOption,		//期货期权，商品期权是这个分类
	CC_Combination,		//组合
	CC_Spot,			//即期
	CC_EFP,				//期转现
	CC_SpotOption,		//现货期权，股指期权是这个分类
	CC_ETFOption,		//个股期权，ETF期权是这个分类

	CC_DC_Spot = 20,	//数币现货
	CC_DC_Swap,			//数币永续
	CC_DC_Future,		//数币期货
	CC_DC_Margin,		//数币杠杆
	CC_DC_Option,		//数币期权

	CC_UserIndex = 90	//自定义指数
} ContractCategory;

/*
 *	K线周期
 */
typedef enum tagKlinePeriod
{
	Tick = -1,
	M1 = 1,
	M3 = 3,
	M5 = 5,
	M10 = 10,
	M15 = 15,
	M30 = 30,
	H1 = 60,
	H2 = 120,
	Day = 0,
	Week = -7,
	Month= -30
} TrPeriod;

static const char* PERIOD_NAME[] =
{
	"Tick",
	"M1",
	"M3",
	"M5",
	"M10",
	"M15",
	"M30",
	"H1",
	"H2",
	"Day",
	"Week",
	"Month"
};



/*
 *	平仓类型
 */
typedef enum tagCoverMode
{
	CM_OpenCover,		//开平
	CM_CoverToday,		//开平昨平今
	CM_UNFINISHED,		//平未了结的
	CM_None			//不区分开平
} CoverMode;

/*
 *	交易模式
 */
typedef enum tagTradingMode
{
	TM_Both,	//多空都支持
	TM_Long,	//只能做多
	TM_LongT1,	//做多T+1
	TM_None = 9	//不能交易
} TradingMode;

/*
*	价格模式
*/
typedef enum tagPriceMode
{
	PM_Both,		//市价限价都支持
	PM_Limit,		//只支持限价
	PM_Market,		//只支持市价
	PM_None = 9		//不支持交易
} PriceMode;

typedef struct _Contract
{
	std::string	m_strCode{};
	std::string	m_strExchg{};
	std::string	m_strName{};
	std::string	m_strProduct{};
	std::string m_strSession{};

	uint32_t	m_maxMktQty{0};
	uint32_t	m_maxLmtQty{0};
	uint32_t	m_minMktQty{0};
	uint32_t	m_minLmtQty{0};

	uint32_t	m_uOpenDate{0};
	uint32_t	m_uExpireDate{0};

	double		m_dLongMarginRatio{0.0};
	double		m_dShortMarginRatio{0.0};

	uint32_t	m_uPrecision{0};
	OptionType	m_optType{OptionType::OT_None};
	std::string m_strUnderlying{};
	double		m_strikePrice{0.0};
	double      m_priceTick{0.0};
	int         m_iVolumeMultiple{0};
	double		m_dUnderlyingScale{0.0};

	_Contract() = default;
} Contract;
typedef std::unordered_map<std::string, Contract> ContractMap;

typedef struct _Commodity
{
	std::string	m_strName{};
	std::string	m_strExchg{};
	std::string	m_strProduct{};
	std::string	m_strCurrency{};
	std::string m_strSession{};
	std::string m_strHoliday{};

	uint32_t	m_uVolScale{};
	double		m_fPriceTick{};
	uint32_t	m_uPrecision{};

	ContractCategory	m_ccCategory{};
	CoverMode			m_coverMode{};
	PriceMode			m_priceMode{};
	TradingMode			m_tradeMode{};
	_Commodity() = default;
} Commodity;
typedef std::unordered_map<std::string, Commodity> CommodityMap;

//==============================================================

#pragma pack(push, 8)

struct WTSTickStruct
{
	char		exchg[MAX_EXCHANGE_LENGTH];
	char		code[MAX_INSTRUMENT_LENGTH];

	double		price;				//最新价
	double		open;				//开盘价
	double		high;				//最高价
	double		low;				//最低价
	double		settle_price;		//结算价

	double		upper_limit;		//涨停价
	double		lower_limit;		//跌停价

	uint32_t	total_volume;		//总成交量
	uint32_t	volume;				//成交量
	double		total_turnover;		//总成交额
	double		turn_over;			//成交额
	uint32_t	open_interest;		//总持
	uint32_t	diff_interest;		//增仓

	uint32_t	trading_date;		//交易日,如20140327
	uint32_t	action_date;		//自然日期,如20140327
	uint32_t	action_time;		//发生时间,精确到毫秒,如105932000
	uint32_t	reserve_;			//占位符

	double		pre_close;			//昨收价
	double		pre_settle;			//昨结算
	uint32_t	pre_interest;		//上日总持

	double		bid_prices[10];		//委买价格
	double		ask_prices[10];		//委卖价格
	double		bid_qty[10];		//委买量
	double		ask_qty[10];		//委卖量
	WTSTickStruct() = default;
};

struct WTSBarStruct
{
public:
	WTSBarStruct() = default;

	uint32_t	date;		//日期
	uint32_t	reserve_;	//占位符
	uint64_t	time;		//时间
	uint64_t 	sign;
	double		open;		//开
	double		high;		//高
	double		low;		//低
	double		close;		//收
	double		settle;		//结算

	double		money;		//成交金额
	uint32_t	vol;		//成交量
	uint32_t	interest;	//持仓量		

	union
	{
		double		hold;	//总持
		double		bid;	//买价，期权专用，主要期权spread比较大，By Wseley @ 2023.05.04
	};

	union
	{
		double		add;	//增仓
		double		ask;	//卖价，期权专用，主要期权spread比较大，By Wseley @ 2023.05.04
	};
};

#pragma pack(pop)